package com.phiture.erp.purchase.core.service.impl;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.phiture.erp.common.constants.ErpNoPrefixConstants;
import com.phiture.erp.common.enums.ErpAuditStatus;
import com.phiture.erp.common.utils.ErpNoGenerator;
import com.phiture.erp.purchase.core.pojo.vo.ErpPurchaseRequestItemPushVO;
import com.phiture.erp.purchase.core.pojo.vo.ErpPurchaseRequestPageReqVO;
import com.phiture.erp.purchase.core.pojo.vo.ErpPurchaseRequestRespVO;
import com.phiture.erp.purchase.core.pojo.vo.ErpPurchaseRequestSaveReqVO;
import com.phiture.erp.purchase.core.service.ErpPurchaseRequestService;
import com.phiture.erp.purchase.dal.entity.ErpPurchaseRequestDO;
import com.phiture.erp.purchase.dal.entity.ErpPurchaseRequestItemsDO;
import com.phiture.erp.purchase.dal.mapper.ErpPurchaseRequestMapper;
import com.phiture.erp.purchase.dal.mapper.PurchaseRequestItemsMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.phiture.erp.common.constants.ErrorCodeConstants.*;

/**
 * 采购申请单 Service 实现类
 *
 * @author lekaihuai
 */
@Service
@Validated
public class ErpPurchaseRequestServiceImpl implements ErpPurchaseRequestService {

    @Resource
    private ErpPurchaseRequestMapper purchaseRequestMapper;
    @Resource
    private PurchaseRequestItemsMapper purchaseRequestItemsMapper;

    @Resource
    private ErpNoGenerator erpNoGenerator;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createPurchaseRequest(ErpPurchaseRequestSaveReqVO createReqVO) {
        // 自动生成 采购申请 编号
        String reqNo = erpNoGenerator.generate(ErpNoPrefixConstants.PUR_REQUEST_NO_PREFIX);
        validateReqNo(reqNo);
        createReqVO.setNo(reqNo).setStatus(ErpAuditStatus.PROCESS.getStatus());
        // 插入
        ErpPurchaseRequestDO purchaseRequest = BeanUtils.toBean(createReqVO, ErpPurchaseRequestDO.class);
        purchaseRequestMapper.insert(purchaseRequest);

        // 插入子表
        createPurchaseRequestItemsList(purchaseRequest.getId(), createReqVO.getPurchaseRequestItemss());
        // 返回
        return purchaseRequest.getId();
    }

    private void validateReqNo(String reqNo){
        boolean exists = purchaseRequestMapper.exists(
                Wrappers.lambdaQuery(ErpPurchaseRequestDO.class)
                        .eq(ErpPurchaseRequestDO::getNo, reqNo)
                        .eq(ErpPurchaseRequestDO::getDeleted, Boolean.FALSE)
        );
        if(exists){
            throw exception(PURCHASE_REQUEST_NO_EXISTS);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePurchaseRequest(ErpPurchaseRequestSaveReqVO updateReqVO) {
        // 校验存在
        validatePurchaseRequestExists(updateReqVO.getId());
        // 更新
        ErpPurchaseRequestDO updateObj = BeanUtils.toBean(updateReqVO, ErpPurchaseRequestDO.class);
        purchaseRequestMapper.updateById(updateObj);

        // 更新子表
        updatePurchaseRequestItemsList(updateReqVO.getId(), updateReqVO.getPurchaseRequestItemss());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePurchaseRequestStatus(Long id, Integer status) {

        boolean approve = ErpAuditStatus.APPROVE.getStatus().equals(status);
        // 1.1 校验存在
        ErpPurchaseRequestDO purchaseRequest = validatePurchaseRequestExists(id);
        // 1.2 校验状态
        if (purchaseRequest.getStatus().equals(status)) {
            throw exception(approve ? PURCHASE_REQUEST_APPROVE_FAIL : PURCHASE_REQUEST_PROCESS_FAIL);
        }
        // 1.3 存在采购订单，无法反审核
        // 获取采购申请明细
        List<ErpPurchaseRequestItemsDO> purchaseRequestItemsList = purchaseRequestItemsMapper.selectList(Wrappers.lambdaQuery(ErpPurchaseRequestItemsDO.class)
                .eq(ErpPurchaseRequestItemsDO::getRequestId, id)
                .gt(ErpPurchaseRequestItemsDO::getPurchaseOrderQty, BigDecimal.ZERO));
        if (!approve && purchaseRequestItemsList.size() > 0) {
            throw exception(PURCHASE_REQUEST_PROCESS_FAIL_EXISTS_ORDER);
        }

        // 2. 更新状态
        int updateCount = purchaseRequestMapper.updateByIdAndStatus(id, purchaseRequest.getStatus(),
                new ErpPurchaseRequestDO().setStatus(status));
        if (updateCount == 0) {
            throw exception(approve ? PURCHASE_REQUEST_APPROVE_FAIL : PURCHASE_REQUEST_PROCESS_FAIL);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePurchaseRequest(Long id) {
        // 校验存在
        validatePurchaseRequestExists(id);

        // 校验是否存在申请单明细的已采购数量大于0，有提示不能删除
        List<ErpPurchaseRequestItemsDO> purchaseRequestItemsList = purchaseRequestItemsMapper.selectList(Wrappers.lambdaQuery(ErpPurchaseRequestItemsDO.class)
                .eq(ErpPurchaseRequestItemsDO::getRequestId, id)
                .gt(ErpPurchaseRequestItemsDO::getPurchaseOrderQty, BigDecimal.ZERO));
        if (purchaseRequestItemsList != null && purchaseRequestItemsList.size() > 0) {
            throw exception(PURCHASE_REQUEST_DELETE_FAIL_EXISTS_ORDER);
        }
        // 删除
        purchaseRequestMapper.deleteById(id);
        // 删除子表
        deletePurchaseRequestItemsByRequestId(id);
    }

    private ErpPurchaseRequestDO validatePurchaseRequestExists(Long id) {
        ErpPurchaseRequestDO purchaseRequest = purchaseRequestMapper.selectById(id);
        if (purchaseRequest == null) {
            throw exception(PURCHASE_REQUEST_NOT_EXISTS);
        }
        return purchaseRequest;
    }
    @Override
    public ErpPurchaseRequestDO getPurchaseRequest(Long id) {
        return purchaseRequestMapper.selectById(id);
    }

    @Override
    public PageResult<ErpPurchaseRequestRespVO> getPurchaseRequestPage(ErpPurchaseRequestPageReqVO pageReqVO) {
        MPJLambdaWrapperX<ErpPurchaseRequestDO> query = new MPJLambdaWrapperX<ErpPurchaseRequestDO>()
                .eqIfPresent(ErpPurchaseRequestDO::getNo, pageReqVO.getNo())
                .betweenIfPresent(ErpPurchaseRequestDO::getBizDate, pageReqVO.getBizDate())
                .eqIfPresent(ErpPurchaseRequestDO::getPersonId, pageReqVO.getPersonId())
                .selectAll(ErpPurchaseRequestDO.class)
                // 选出申请单明细的物理ID，数量，单价，金额，价税合计，单位
                .selectAll(ErpPurchaseRequestItemsDO.class)
                        .selectAs(ErpPurchaseRequestItemsDO::getId, "itemId");

        query.leftJoin(ErpPurchaseRequestItemsDO.class, ErpPurchaseRequestItemsDO::getRequestId, ErpPurchaseRequestDO::getId)
        .orderByDesc(ErpPurchaseRequestDO::getId)
        .orderByDesc(ErpPurchaseRequestItemsDO::getId);

        if (pageReqVO.getMaterialId() != null) {
            query.eq(pageReqVO.getMaterialId() != null, ErpPurchaseRequestItemsDO::getMaterialId, pageReqVO.getMaterialId());
        }

        return purchaseRequestMapper.selectJoinPage(pageReqVO, ErpPurchaseRequestRespVO.class, query);
    }

    // ==================== 子表（采购申请单明细） ====================
    @Override
    public List<ErpPurchaseRequestItemsDO> getPurchaseRequestItemsListByRequestIds(List<ErpPurchaseRequestItemPushVO> requestItems) {
        // 循环申请单ID,查询申请单明细，最后所有的申请单明细放入一个list中
        List<ErpPurchaseRequestItemsDO> purchaseRequestItemsList = new ArrayList<>();
        for (ErpPurchaseRequestItemPushVO item : requestItems) {
            List<ErpPurchaseRequestItemsDO> list = purchaseRequestItemsMapper.selectList(Wrappers.lambdaQuery(ErpPurchaseRequestItemsDO.class)
                    .eq(ErpPurchaseRequestItemsDO::getId, item.getSourceBillDetailId())
                    .eq(ErpPurchaseRequestItemsDO::getRequestId, item.getSourceBillId()));
            if (list != null && list.size() > 0) {
                purchaseRequestItemsList.addAll(list);
            }
        }
        return purchaseRequestItemsList;
    }

    @Override
    public int updatePurchaseRequestItem(ErpPurchaseRequestItemsDO item) {
        return purchaseRequestItemsMapper.updateById(item);
    }

    @Override
    public ErpPurchaseRequestItemsDO getPurchaseRequestItemsListBId(Long id) {
        return purchaseRequestItemsMapper.selectById(id);
    }

    @Override
    public void savePurchaseRequest(ErpPurchaseRequestDO requestDO) {
        purchaseRequestMapper.insert(requestDO);
    }

    @Override
    public void savePurchaseRequestItem(ErpPurchaseRequestItemsDO requestItemsDO) {
        purchaseRequestItemsMapper.insert(requestItemsDO);
    }

    @Override
    public List<ErpPurchaseRequestItemsDO> getPurchaseRequestItemsListByRequestId(Long requestId) {
        return purchaseRequestItemsMapper.selectListByRequestId(requestId);
    }

    private void createPurchaseRequestItemsList(Long requestId, List<ErpPurchaseRequestItemsDO> list) {
        list.forEach(o -> o.setRequestId(requestId));
        purchaseRequestItemsMapper.insertBatch(list);
    }

    private void updatePurchaseRequestItemsList(Long requestId, List<ErpPurchaseRequestItemsDO> list) {
        deletePurchaseRequestItemsByRequestId(requestId);
		list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createPurchaseRequestItemsList(requestId, list);
    }

    private void deletePurchaseRequestItemsByRequestId(Long requestId) {
        purchaseRequestItemsMapper.deleteByRequestId(requestId);
    }


}